<?php
/**
 * Created by PhpStorm.
 * User: jack Wang
 * Date: 2021/10/29
 * Time: 13:35
 */

class Activity_model extends Base_Model
{
    private $conn;

    public function __construct()
    {
        parent::__construct();
        $this->conn = getRedis();
        $this->conn->selectDb(3);
    }

    public function addScore($uid, $step, $score, $coin, $after_step, $num)
    {
        $data = [
            'uid' => $uid,
            'step' => $step,
            'score' => $score,
            'coin' => $coin,
            'after_step' => $after_step,
            'use_num' => $num,
            'init_time' => time()
        ];
        return $this->commonInsert('activity_score', $data);
    }

    public function getUseNum($uid)
    {
        $res = $this->commonQuery('sum(use_num) num', 'uid=' . $uid, 'activity_score');
        return $res[0]['num'];
    }

    public function updateScore($uid, $score)
    {
        $before = $this->commonQuery('score', ['id' => $uid], 'users');
        $score += $before[0]['score'];
        return $this->commonUpdate('users', ['score' => $score], ['id' => $uid]);
    }

    public function stepRank($rank)
    {
        $uid = array_column($rank, 'uid');
        $res = $this->db->select('id,nickname,image')
            ->where_in('id', $uid)
            ->get('users');
        return $res->num_rows() ? $res->result_array() : false;
    }

    public function addActivityTurnover($uid, $num, $type = 1, $award)
    {
        $res = $this->commonInsert('blind_box_award', ['uid' => $uid, 'num' => $num, 'type' => $type, 'award' => $award]);
        return $res;
    }

    public function getExchangePropNum($uid, $index)
    {
        return $this->commonQuery('count(id) num', ['uid' => $uid, 'award_index' => $index], 'blind_box_char_exchange');
    }

    public function getChars($uid)
    {
        $key = $uid . "_charNum";
        return $this->conn->hGetAll($key);
    }

    /**
     * @param $uid   用户id
     * @param $propId 道具id
     * @param $num 获得数量 + 为获得 - 为消耗
     * @param $desc 记录背包道具流水描述信息
     * @return bool
     */
    public function addRucksack($uid, $propId, $num, $desc)
    {
        if ($num > 0) {
            $value = "num+" . $num;
        } else {
            $value = "num" . $num;
        }
        //先做修改操作
        $rowData = [
            'uid' => $uid,
            'prid' => $propId,
            'num' => $num,
            'init_time' => time()
        ];
        $this->db->set('num', $value, false)
            ->where(array('prid' => $propId, 'uid' => $uid))
            ->limit(1)
            ->update('rucksack');
        //若修改失败，则说明该用户没有该道具
        if (!$this->db->affected_rows()) {
            $sql = $this->db->insert_string('rucksack', $rowData) . ' ON DUPLICATE KEY UPDATE `num`=' . $value;
            $this->db->query($sql);
            if (!$this->db->affected_rows()) {
                return false;
            }
        }
        $rowData['desc'] = $desc;
        //增加流水
        $res = $this->commonInsert('prop_log', $rowData);
        return $res ? true : false;
    }

    public function getPropNameById($id)
    {
        return $this->commonQuery('prop_name', ['id' => $id], 'prop');
    }

    public function addExchangeLog($uid, $useIndex, $awardIndex, $initTime)
    {
        $data = [
            'uid' => $uid,
            'use_index' => $useIndex,
            'award_index' => $awardIndex,
            'init_time' => $initTime
        ];
        $this->commonInsert('blind_box_char_exchange', $data);
    }

    public function changeCharNum($uid, $index, $num)
    {
        $charKey = $uid . '_charNum';
        $after_num = $this->conn->hIncrBy($charKey, $index, $num);
        if ($num < 0 && $after_num < 0) {
            //扣除道具数量不够，先将数量加回去,返回错误
            $this->conn->hIncrBy($charKey, $index, -$num);
            return false;
        }
        return true;
    }

    public function changeCoins($uid, $coins, $text="")
    {
        $coin = $this->commonQuery('coin', ['id' => $uid], 'users');
        if ($coins < 0 && ($coin[0]['coin'] + $coins) < 0) {
            return false;
        }
        $coinStr = 'coin+' . $coins;
        //修改金币记录
        $this->db->set('coin', $coinStr, false)->where('id', $uid)->update('users');
        //添加金币使用流水
        $this->commonInsert('coin_log', ['uid' => $uid, 'amount' => $coins, 'desc' => $text, 'init_time' => time()]);
        return $this->db->affected_rows() ? true : false;
    }

    public function getExchangePropLog($uid)
    {
        $query = $this->db->select('award_index,count(id) num')
            ->where(['uid' => $uid])
            ->group_by('award_index')
            ->get('blind_box_char_exchange');
        return $query->num_rows() ? $query->result_array() : [];
    }

    public function addBlindBoxFriend($data)
    {
        return $this->commonInsert('blind_friend', $data);
    }

    public function getBlindBoxNote($uid, $type)
    {
        $query = $this->db->select("id,images,code,content")
            ->where(['uid !=' => $uid, 'type' => $type])
            ->order_by('id', 'RANDOM')
            ->limit(1)
            ->get('blind_friend');
        return $query->num_rows() ? $query->result_array() : false;
    }

    public function addGetBlindBoxFriend($uid, $noteId)
    {
        return $this->commonInsert('blind_friend_log', ['uid' => $uid, 'note_id' => $noteId, 'init_time' => time()]);
    }

    public function myBlindBoxNote($uid, $type)
    {
        //我放入的纸条
        if ($type == 1) {
            return $this->commonQuery('id,code,type,content,images', ['uid' => $uid], 'blind_friend');
        } else {
            $this->db->select('b.id,code,b.type,b.content,images')
                ->from('blind_friend_log a')
                ->join('blind_friend b', 'a.note_id=b.id', 'left')
                ->where(['a.uid' => $uid]);
            $query = $this->db->get();
            return $query->num_rows() ? $query->result_array() : '';
        }
    }

    public function getMagicBoxNum($uid)
    {
        $res = $this->db->select('prid,num')->where_in('prid', [24, 25])->where('uid', $uid)->get('rucksack');
        return $res->num_rows() ? $res->result_array() : [];
    }

    public function getMagicPropRate()
    {
        return $this->commonQuery('prid,rate,type',['activity_type'=>1],'activity_award_config');
    }

    public function addOpenMagicBox($uid, $prid, $type, $num)
    {
        $value = [
            'uid' => $uid,
            'prid' => $prid,
            'type' => $type,
            'num' => $num,
            'init_time' => time()
        ];
        return $this->commonInsert('magic_box_award', $value);
    }

    public function getRateFromCaption($key)
    {
        $this->conn->selectDb(4);
        $redis_key = "Rate_".$key;
        $rate = $this->conn->get($redis_key);
        if (!$rate){
            $res = $this->commonQuery('assign_value',['assign_name'=>$key],'capital_assign');
            $rate = $res[0]['assign_value'];
            if ($rate){
                $this->conn->set($redis_key,$rate);
            }else{
                return false;
            }
        }
        return $rate;
    }

    public function useCoinGetTicket()
    {
        //获取活动的截止时间
        list($start,$end) = config_item('ticketActivityTime');
        $date = date("Y-m-d H:i:s");
        if ($date < $start)
        {
            die("活动未开启");
        }
        if ($date > $end)
        {
            die("活动未开始");
        }
        $list =  $this->getUseCoin();
        $award = $this->coinGetTicket();
        foreach ($list as $k => $v) {
            $coinValue[$v['uid']] = $v['useCoin'];
            foreach ($award as $kk => $vv) {
                if ($coinValue[$v['uid']] >= $kk) { //匹配应有的抽奖券数量
                    $ticketValue[$v['uid']] = $vv;
                }
            }
        }
        //将用户消耗的金币数以及应有的抽奖券数放到redis缓存中
        if (!empty($coinValue))
            $this->conn->hMSet(RedisKey::ACTIVITY_COIN_NUM,$coinValue,10*86400);
        if (!empty($ticketValue))
            $this->conn->hMSet(RedisKey::ACTIVITY_TICKET_NUM,$ticketValue,10*86400);
        echo date("Y-m-d H:i:s")."执行成功!".PHP_EOL;
    }

    public function getUseCoin()
    {
        list($start,$end) = config_item('ticketActivityTime');
        $startTime = strtotime($start);
        $endTime = strtotime($end);
        $conditions = [
            'init_time >=' => $startTime,
            'init_time <' => $endTime,
            'amount <' => 0,
        ];
        //从金币流水中获得指定时间内用户消耗金币的总数
        $res = $this->db->select('uid,sum(-amount) useCoin')->where($conditions)->group_by('uid')->get('coin_log');
        return $res->num_rows() ? $res->result_array() : "";
    }

    public function coinGetTicket()
    {
        //key为消耗金币数，value为应该拥有的抽奖券数，个人最多16个
        return [
            10 => 1,
            50 => 2,
            100 => 3,
            150 => 4,
            200 => 5,
            250 => 6,
            310 => 7,
            370 => 8,
            420 => 9,
            530 => 10,
            650 => 11,
            780 => 12,
            920 => 13,
            1100 => 14,
            1600 => 15,
            2300 => 16,
        ];
    }

    public function getUserTicket($uid)
    {
        $res = $this->conn->hGet(RedisKey::ACTIVITY_TICKET_NUM, $uid);
        return $res ? $res : 0;
    }

    public function getUserUseTicket($uid)
    {
        $res = $this->conn->sCard(RedisKey::ACTIVITY_TICKET_AWARD.$uid);
        return $res ? $res : 0;
    }

    public function getUserPuzzlePieces($uid)
    {
        $res = $this->conn->sMembers(RedisKey::ACTIVITY_TICKET_AWARD.$uid);
        return $res ? $res : [];
    }

    public function addPiecesRedis($uid,$index)
    {
        $res = $this->conn->sAdd(RedisKey::ACTIVITY_TICKET_AWARD.$uid,$index);
        return $res ? $res : 0;
    }

    public function addPiecesDb($uid,$index)
    {
        $data = [
            'uid' => $uid,
            'index' => $index,
            'init_time' => time(),
        ];
        $this->commonInsert('get_puzzle_index',$data);
    }

    public function havePuzzleAward($uid,$index,$isRight)
    {
        //a只有一个奖励
        if ($index == 'a') {
            $isRight = 1;
        }
        $res = $this->db->select('id')
            ->where('uid',$uid)
            ->where('index',$index)
            ->where('is_right',$isRight)
            ->get('get_puzzle_award');
        return $res->num_rows();
    }

    public function PuzzleAward($uid,$type)
    {
        //通过$type获取应该获得的奖励 awardType 奖励类型 1:金币 2;道具
        switch ($type){
            case 'a' :
                $awardType = 1;
                $award = 300;
                break;
            case 'b' :
                $awardType = 1;
                $award = 500;
                break;
            case 'c' :
                $awardType = 2;
                $award = 3;
                break;
            case 'd' :
                $awardType = 2;
                $award = 24;
                break;
            case 'e':
                $awardType = 2;
                $award = 25;
                break;
            default :
                return false;
        }
        //发放奖励
        //金币
        if ($awardType == 1) {
            $this->changeCoins($uid,$award,'集拼图碎片获得奖励');
        }else{
            $this->addRucksack($uid,$award,1,'集拼图碎片获得奖励');
        }
        return true;
    }

    public function addPuzzleAwardLog($uid,$type,$isRight)
    {
        $content = $this->PuzzleAwardList();
        $data = [
            'uid' => $uid,
            'index' => $type,
            'content' => $content[$type],
            'is_right' => $isRight,
            'init_time' => time(),
        ];
        return $this->commonInsert('get_puzzle_award',$data);
    }

    public function PuzzleAwardList()
    {
        return [
            'a' => '300金币',
            'b' => '500金币',
            'c' => '双倍经验卡',
            'd' => '魔盒',
            'e' => '魔法钥匙',
        ];
    }

    public function openNewYearCaseLog($uid,$index,$ticketNum,$prop)
    {
        $data = [
            'uid' => $uid,
            'index' => $index,
            'ticket_num' => $ticketNum,
            'award' => $prop,
            'init_time' => time(),
        ];
        return $this->commonInsert('newyear_opencase_log',$data);
    }

    public function checkUserOpenNewYearCase($uid, $index)
    {
        $res = $this->db->select('count(id) num')->from('newyear_opencase_log')
            ->where('uid', $uid)
            ->where('index', $index)
            ->get();
        return $res->num_rows() ? $res->row_array() : false;
    }

    public function newYearUsedCoin()
    {
        //获取活动的截止时间
        list($start, $end) = config_item('newYearCaseTime');
        $date = date("Y-m-d H:i:s");
        if ($date < $start) {
            die("活动未开启");
        }
        if ($date > $end) {
            die("活动未开始");
        }
        $list = $this->getUseCoinByTime($start, $end);
        if (!empty($list)){
            foreach ($list as $k => $v) {
                $coinValue[$v['uid']] = $v['useCoin'];
            }
        }
        //将用户消耗的金币数以及应有的抽奖券数放到redis缓存中
        if (!empty($coinValue))
            $this->conn->hMSet(RedisKey::ACTIVITY_NEWYEAR_USED_COIN, $coinValue, 5 * 86400);
        echo date("Y-m-d H:i:s") . "执行成功!" . PHP_EOL;
    }

    public function getUseCoinByTime($start, $end)
    {
        $startTime = strtotime($start);
        $endTime = strtotime($end);
        $conditions = [
            'init_time >=' => $startTime,
            'init_time <' => $endTime,
            'amount <' => 0,
        ];
        //从金币流水中获得指定时间内用户消耗金币的总数
        $res = $this->db->select('uid,sum(-amount) useCoin')->where($conditions)->group_by('uid')->get('coin_log');
        return $res->num_rows() ? $res->result_array() : "";
    }

    public function getUsedCaseIndex($uid)
    {
        $res = $this->db->select('index')
            ->from('newyear_opencase_log')
            ->where('uid', $uid)
            ->order_by('index','asc')
            ->get();
        return $res->num_rows() ? $res->result_array() : [];
    }

    public function getAwardInfo()
    {
        $res = $this->db->select('uid,ticket_num,index,award,username')
            ->from('newyear_opencase_log')
            ->join('users u','uid = u.id','left')
            ->order_by('init_time desc')
            ->where('award != ','')
            ->limit(20)
            ->get();
        return $res->num_rows() ? $res->result_array() : [];
    }

    public function getPropNameByIds($idArray)
    {
        $query = $this->db->select('id,prop_name')
            ->where_in('id', $idArray)
            ->from('prop')
            ->get();
        return $query->num_rows() ? $query->result_array() : [];
    }

    public function checkUserExchangeNewYearPropNum($uid, $index)
    {
        $query = $this->db->select('count(1) num')
            ->from('new_year_exchange_log')
            ->where('uid', $uid)
            ->where('index', $index)
            ->get();
        return $query->num_rows() ? $query->row_array() : 0;
    }

    public function addNyExchangeLog($uid, $data)
    {
        $param = [
            'uid' => $uid,
            'index' => $data['index'],
            'prop_id' => empty($data['propId']) ? $data['coin'] : $data['propId'],
            'type' => empty($data['propId']) ? 0 : 1,
            'used_ticket' => $data['ticket'],
            'init_time' => time(),
        ];
        return $this->commonInsert('new_year_exchange_log', $param);
    }
}